package com.breeze.blockchain.service.impl;

import static com.breeze.blockchain.common.exception.BizErrorCode.USERNAME_MOBILE_EMAIL_EXIST;
import static com.breeze.blockchain.common.exception.BizErrorCode.USERNAME_OR_PASS_ERROR;
import static com.breeze.blockchain.mybatis.entity.table.AdminTable.ADMIN;
import static com.breeze.components.core.exception.error.ErrorCode.Business.OPERATE_FAIL_ERROR;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.breeze.blockchain.auth.util.AdminUserUtil;
import com.breeze.blockchain.auth.util.AppUserUtil;
import com.breeze.blockchain.mybatis.entity.AdminDo;
import com.breeze.blockchain.mybatis.mapper.AdminMapper;
import com.breeze.blockchain.service.AdminService;
import com.breeze.blockchain.service.RoleService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.If;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

/**
 * 管理员表 服务层实现。
 *
 * @author breeze
 * @since 2024-05-11 22:55:04
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, AdminDo> implements AdminService {

  @Resource RoleService roleService;

  @Override
  public AdminDo login(String username, String password) {
    var admin = this.getExistUserByUserName(username);
    admin.checkStatus();
    var role = roleService.getExistRoleById(admin.getRoleId());
    role.checkRoleStatus();
    USERNAME_OR_PASS_ERROR.isTrue(DigestUtil.bcryptCheck(password, admin.getPassword()));
    AdminUserUtil.checkDisable(admin.getId());
    AdminUserUtil.login(admin.getId());
    admin.setAccessToken(AppUserUtil.getTokenValue());
    return admin;
  }

  @Override
  public void saveAdmin(AdminDo admin) {
    var existAdmin = getExistUserByUserName(admin.getUsername());
    USERNAME_MOBILE_EMAIL_EXIST.isNull(existAdmin);
    admin.setPassword(DigestUtil.bcrypt(admin.getPassword()));
    OPERATE_FAIL_ERROR.isTrue(this.save(admin));
  }

  @Override
  public boolean updateAdmin(AdminDo admin) {
    this.getExistById(admin.getId());
    if (StrUtil.isNotEmpty(admin.getPassword())) {
      admin.setPassword(DigestUtil.bcrypt(admin.getPassword()));
    }
    return this.updateById(admin);
  }

  @Override
  public Page<AdminDo> adminPage(
      Page<AdminDo> toPage, String username, String mobile, String nickname) {
    return this.queryChain()
        .where(
            ADMIN
                .USERNAME
                .like(username, If::hasText)
                .and(ADMIN.MOBILE.like(mobile, If::hasText))
                .and(ADMIN.NICKNAME.like(mobile, If::hasText)))
        .orderBy(ADMIN.ID.desc())
        .page(toPage);
  }
}
